package com.yxinsur.imc.business.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yxinsur.imc.business.domain.ImcFundBrokerExpression;
import com.yxinsur.imc.business.domain.ImcFundBrokerVariable;
import com.yxinsur.imc.business.domain.ImcFundOrderVariable;
import com.yxinsur.imc.business.enums.ExpenseExpressionMsgTypeEnum;
import com.yxinsur.imc.business.enums.FundMonthlyStrategyEnum;
import com.yxinsur.imc.business.enums.IsDeletedEnum;
import com.yxinsur.imc.business.form.FundBrokerExpressionForm;
import com.yxinsur.imc.business.form.FundBrokerForm;
import com.yxinsur.imc.business.mapper.ImcBrokerMapper;
import com.yxinsur.imc.business.mapper.ImcFundBrokerExpressionMapper;
import com.yxinsur.imc.business.mapper.ImcFundBrokerVariableMapper;
import com.yxinsur.imc.business.service.IImcFundBrokerExpressionService;
import com.yxinsur.imc.business.vo.ContractExpenseExpressionMessageVo;
import com.yxinsur.imc.business.vo.FundBrokerExpressionVo;
import com.yxinsur.imc.common.core.domain.AjaxResult;
import com.yxinsur.imc.common.exception.BusinessException;
import com.yxinsur.imc.common.utils.DateUtils;
import com.yxinsur.imc.common.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 人员口径（暨口径达式配置）Service业务层处理
 *
 * @author imc
 * @date 2021-10-29
 */
@Service
@Slf4j
public class ImcFundBrokerExpressionServiceImpl extends ServiceImpl<ImcFundBrokerExpressionMapper, ImcFundBrokerExpression> implements IImcFundBrokerExpressionService {
    @Autowired
    private ImcFundBrokerExpressionMapper imcFundBrokerExpressionMapper;
    @Autowired
    private ImcRecnExpenseServiceImpl recnExpenseService;
    @Autowired
    private ImcBrokerMapper imcBrokerMapper;
    @Autowired
    private ImcFundBrokerVariableMapper fundBrokerVariableMapper;

    /**
     * 查询人员口径（暨口径达式配置）
     *
     * @param id 人员口径（暨口径达式配置）ID
     * @return 人员口径（暨口径达式配置）
     */
    @Override
    public ImcFundBrokerExpression selectImcFundBrokerExpressionById(Long id) {
        return imcFundBrokerExpressionMapper.selectImcFundBrokerExpressionById(id);
    }

    /**
     * 查询人员口径（暨口径达式配置）列表
     *
     * @param imcFundBrokerExpression 人员口径（暨口径达式配置）
     * @return 人员口径（暨口径达式配置）
     */
    @Override
    public List<ImcFundBrokerExpression> selectImcFundBrokerExpressionList(ImcFundBrokerExpression imcFundBrokerExpression) {
        return imcFundBrokerExpressionMapper.selectImcFundBrokerExpressionList(imcFundBrokerExpression);
    }

    /**
     * 新增人员口径（暨口径达式配置）
     *
     * @param fundBrokerForm 人员口径（暨口径达式配置）
     * @return 结果
     */
    @Override
    public int insertImcFundBrokerExpression(FundBrokerForm fundBrokerForm) {
        List<FundBrokerExpressionForm> fundBrokerExpressionList = fundBrokerForm.getFundBrokerExpressionList();
        Long fundId = fundBrokerForm.getFundId();
        ArrayList<ImcFundBrokerExpression> expressions = new ArrayList<>();
        for (FundBrokerExpressionForm fundBrokerExpressionForm : fundBrokerExpressionList) {
            ImcFundBrokerExpression imcFundBrokerExpression = new ImcFundBrokerExpression();
            BeanUtils.copyProperties(fundBrokerExpressionForm,imcFundBrokerExpression);
            String variableName = fundBrokerExpressionForm.getVariableName();
            QueryWrapper<ImcFundBrokerVariable> wrapper = new QueryWrapper<>();
            wrapper.eq("variable_name",variableName);
            ImcFundBrokerVariable variable = fundBrokerVariableMapper.selectOne(wrapper);
            imcFundBrokerExpression.setBrokerVariableId(variable.getId());
            imcFundBrokerExpression.setBrokerStrategy(fundBrokerExpressionForm.getStrategyCode());
            imcFundBrokerExpression.setFundId(fundId);
            imcFundBrokerExpression.setCreateId(SecurityUtils.getUsername());
            imcFundBrokerExpression.setCreateTime(DateUtils.getNowDate());
            imcFundBrokerExpression.setUpdateId(SecurityUtils.getUsername());
            imcFundBrokerExpression.setUpdateTime(DateUtils.getNowDate());
            imcFundBrokerExpression.setTenantId(SecurityUtils.getTenantId());
            imcFundBrokerExpression.setIsDeleted(IsDeletedEnum.N.getCode());
            expressions.add(imcFundBrokerExpression);
        }
        return imcFundBrokerExpressionMapper.insertImcFundBrokerExpressionList(expressions);
    }

    /**
     * 修改人员口径（暨口径达式配置）
     *
     * @param fundBrokerForm 人员口径（暨口径达式配置）
     * @return 结果
     */
    @Override
    public int updateImcFundBrokerExpression(FundBrokerForm fundBrokerForm) {
        List<Long> idList = fundBrokerForm.getFundBrokerExpressionList().stream().map(FundBrokerExpressionForm::getId).collect(Collectors.toList());
        Long[] idArr = new Long[idList.size()];
        idList.toArray(idArr);
        //删除旧口径
        this.deleteImcFundBrokerExpressionByIds(idArr);
        //新增新口径
        return insertImcFundBrokerExpression(fundBrokerForm);
    }

    /**
     * 批量删除人员口径（暨口径达式配置）
     *
     * @param ids 需要删除的人员口径（暨口径达式配置）ID
     * @return 结果
     */
    @Override
    public int deleteImcFundBrokerExpressionByIds(Long[] ids) {
        return imcFundBrokerExpressionMapper.logicalDeletedByIds(ids);
    }

    /**
     * 删除人员口径（暨口径达式配置）信息
     *
     * @param id 人员口径（暨口径达式配置）ID
     * @return 结果
     */
    @Override
    public int deleteImcFundBrokerExpressionById(Long id) {
        return imcFundBrokerExpressionMapper.deleteImcFundBrokerExpressionById(id);
    }


    /**
     * 根据基本法id 获得相应的人员口径配置信息
     * @param fundId
     * @return
     */
    @Override
    public List<FundBrokerExpressionVo> selectImcFundBrokerExpressionByFundId(Long fundId) {
        ImcFundBrokerExpression imcFundBrokerExpression = new ImcFundBrokerExpression();
        imcFundBrokerExpression.setFundId(fundId);
        imcFundBrokerExpression.setIsDeleted("0");
        imcFundBrokerExpression.setTenantId(SecurityUtils.getTenantId());
        List<ImcFundBrokerExpression> expressionList = imcFundBrokerExpressionMapper.selectImcFundBrokerExpressionList(imcFundBrokerExpression);
        ArrayList<FundBrokerExpressionVo> expressionVos = new ArrayList<>();
        for (ImcFundBrokerExpression expression : expressionList) {
            FundBrokerExpressionVo fundBrokerExpressionVo = new FundBrokerExpressionVo();
            BeanUtils.copyProperties(expression,fundBrokerExpressionVo);
            ImcFundBrokerVariable fundBrokerVariable = fundBrokerVariableMapper.selectById(expression.getBrokerVariableId());
            fundBrokerExpressionVo.setVariableName(fundBrokerVariable.getVariableName());
            fundBrokerExpressionVo.setStrategyCode(expression.getBrokerStrategy());
            expressionVos.add(fundBrokerExpressionVo);
        }
        return expressionVos;
    }

    /**
     * 校验人员口径表达式
     * @param fundBrokerForm
     * @return
     */
    @Override
    @Transactional
    public AjaxResult checkExpenseExpression(FundBrokerForm fundBrokerForm) {
        StringBuilder sqlStr = new StringBuilder();
        StringBuilder tagStr = new StringBuilder();
        ContractExpenseExpressionMessageVo messageVo = new ContractExpenseExpressionMessageVo();

        // 转换
        for (FundBrokerExpressionForm item : fundBrokerForm.getFundBrokerExpressionList()) {

            // 协议口径变量（如果遇到括弧则直接跳过转换，避免转换成空格）
            String variableName = item.getVariableName();
            String variableLabel = item.getVariableLabel();
            if ("left_bracket".equals(variableName) || "right_bracket".equals(variableName)) {
                QueryWrapper<ImcFundBrokerVariable> queryWrapper = new QueryWrapper<>();//左右括号为空,这里做下处理
                queryWrapper.eq("variable_name",variableName);
                ImcFundBrokerVariable fundBrokerVariable = fundBrokerVariableMapper.selectOne(queryWrapper);
                sqlStr.append(fundBrokerVariable.getVariableLabel());
                tagStr.append(fundBrokerVariable.getVariableLabel());
            } else {
                sqlStr.append(variableName);
                tagStr.append(variableLabel);
            }


            // 运算符
            String operator = item.getOperator();
            if (StrUtil.isNotBlank(operator)) {
                sqlStr.append(" ").append(recnExpenseService.transOperator(operator, ExpenseExpressionMsgTypeEnum.SQL.name()));
                tagStr.append(" ").append(recnExpenseService.transOperator(operator, ExpenseExpressionMsgTypeEnum.TAG.name()));
            }

            // 处理策略
            String brokerStrategy = item.getStrategyCode();
            if (ObjectUtil.isNotNull(brokerStrategy)) {
                //code获得枚举值的value
                tagStr.append(" ").append(FundMonthlyStrategyEnum.getCode(brokerStrategy));
            }

            // 协议口径变量（数值）
            String variableValue = item.getVariableValue();
            if (StrUtil.isNotBlank(variableValue)) {
                // 处理策略为“结算上月”
                if(FundMonthlyStrategyEnum.A.name().equals(brokerStrategy)){
                    Date addDate = DateUtils.addMonths(new Date(), -1);
                    String yearMonth = DateUtils.parseDateToStr(DateUtils.YYYY_MM, addDate);
                    sqlStr.append(" '").append(yearMonth+"-").append(variableValue).append("'");
                    tagStr.append(" '").append(yearMonth+"-").append(variableValue).append("'");
                }else if (FundMonthlyStrategyEnum.B.name().equals(brokerStrategy)) {
                    String yearMonth = DateUtils.parseDateToStr(DateUtils.YYYY_MM, new Date());
                    sqlStr.append(" '").append(yearMonth+"-").append(variableValue).append("'");
                    tagStr.append(" '").append(yearMonth+"-").append(variableValue).append("'");
                } else if(FundMonthlyStrategyEnum.C.name().equals(brokerStrategy)){
                    Date addDate = DateUtils.addMonths(new Date(), 1);
                    String yearMonth = DateUtils.parseDateToStr(DateUtils.YYYY_MM, addDate);
                    sqlStr.append(" '").append(yearMonth+"-").append(variableValue).append("'");
                    tagStr.append(" '").append(yearMonth+"-").append(variableValue).append("'");
                }else{
                    sqlStr.append(" '").append(variableValue).append("'");
                    tagStr.append(" '").append(variableValue).append("'");
                }
            }

            // 逻辑运算符
            String logicalOperator = item.getLogicalOperator();
            if (StrUtil.isNotBlank(logicalOperator) && !"0".equals(logicalOperator)) {
                sqlStr.append(" ").append(recnExpenseService.transLogicalOperator(logicalOperator, ExpenseExpressionMsgTypeEnum.SQL.name())).append(" ");
                tagStr.append(" ").append(recnExpenseService.transLogicalOperator(logicalOperator, ExpenseExpressionMsgTypeEnum.TAG.name())).append(" ");
            }
        }
        log.info("基本法Id: " + fundBrokerForm.getFundId());
        log.info("基本法查代理人对应口径SQL： " + sqlStr.toString());
        log.info("基本法查代理人对应口径TAG： " + tagStr.toString());
        messageVo.setSqlStr(sqlStr.toString());
        messageVo.setTagStr(tagStr.toString());
        log.info("messageVo： " + JSONUtil.toJsonStr(messageVo));
        try {
            this.imcBrokerMapper.getImcBrokerByCriteria(sqlStr.toString(),SecurityUtils.getTenantId());
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new BusinessException(JSONUtil.toJsonStr(messageVo));
        }
        return AjaxResult.success(messageVo);
    }
}
